﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.Security;
using Controller2.BLL;
using Controller2.Models;
using Controller2.Models.ViewModels;
using Telerik.Web.Mvc;

namespace Controller2.Controllers
{
    [Authorize]
    public class ClienteController : Controller
    {
        #region ViewModels
        ControllerBDModelContainer db = new ControllerBDModelContainer();
        ClientesViewModel viewModel = new ClientesViewModel();
        #endregion

        #region Index
        [Authorize(Roles = "SysAdmin, Administrador, Gerente, DiretorArte")]
        public ActionResult Index()
        {
            ViewBag.IsInRole = User.IsInRole("SysAdmin") || User.IsInRole("Administrador") || User.IsInRole("Gerente") ? true : false;
            Session["Request"] = null;
            Session["TipoFuncionario"] = null;
            Session["IdPessoa"] = null;
            var dic = new Dictionary<string, int>();
            dic.Add("Código", 1);
            dic.Add("Nome", 2);
            dic.Add("E-mail", 3);
            dic.Add("Cidade", 4);
            ViewBag.Pesquisa = PesquisaBll.PreencheComboPesquisa(dic, "Consulta de Clientes: ");
            Session["texto"] = "";
            Session["filtro"] = 0;
            if (Session["Mensagem"] != null)
            {
                ViewBag.Msg = Session["Mensagem"].ToString();
                Session["Mensagem"] = null;
            }
            return View();
        }

        [Authorize(Roles = "SysAdmin, Administrador, Gerente, DiretorArte")]
        [GridAction]
        public ActionResult AjaxGrid()
        {
            var texto = Session["texto"].ToString();
            var filtro = Convert.ToInt32(Session["filtro"]);
            var cli = new GridModel { Data = viewModel.Listar(db, texto, filtro) };
            return View(cli);
        }

        [Authorize(Roles = "SysAdmin, Administrador, Gerente, DiretorArte")]
        [HttpPost]
        public ActionResult Pesquisa(string texto, int filtro)
        {
            Session["texto"] = texto;
            Session["filtro"] = filtro;
            return Json(new { salvo = true });
        }

        [Authorize(Roles = "SysAdmin, Administrador, Gerente, DiretorArte")]
        public ActionResult PesquisaCliente()
        {
            Session["pesquisaCliente"] = "";
            ViewBag.Pesquisa = PesquisaBll.PreencheComboPesquisaCliente();
            return View();
        }

        [Authorize(Roles = "SysAdmin, Administrador, Gerente, DiretorArte")]
        [HttpPost]
        public ActionResult TermosPesquisa(string texto)
        {
            Session["pesquisaCliente"] = texto;
            return Json(new { salvo = true });
        }

        [Authorize(Roles = "SysAdmin, Administrador, Gerente, DiretorArte")]
        [GridAction]
        public ActionResult AjaxPesquisaCliente()
        {
            var pesquisaCliente = Session["pesquisaCliente"].ToString();
            var cli = new GridModel { Data = viewModel.Procura(db, pesquisaCliente) };
            return View(cli);
        }
        #endregion

        #region Detalhes do Cliente
        [Authorize]
        public ActionResult DetalheCliente()
        {
            if (User.Identity.IsAuthenticated)
            {
                var user = User.Identity.Name;
                var role = Roles.GetRolesForUser(user).FirstOrDefault();
                if (!role.Equals("Cliente"))
                {
                    Session["Mensagem"] = "Cadastro exclusivo para pessoas com acesso de CLIENTE!";
                    return RedirectToAction("Index", "Cliente");
                }
                var cli = viewModel.GetClienteCompleto(db, user);
                if (!cli.Username.Equals(User.Identity.Name))
                {
                    var autorizado = role.Equals("SysAdmin") ? true : role.Equals("Administrador") ? true : role.Equals("Gerente") ? true : role.Equals("Funcionario") ? true : false;
                    if (!autorizado)
                    {
                        Session["MensagemErro"] = "Você não tem autorização para ver os detalhes deste cliente.";
                        return RedirectToAction("NaoAutorizado", "Erros");
                    }
                }
                return View(cli);
            }
            return RedirectToAction("NaoAutorizado", "Erros");
        }
        #endregion

        #region Cadastros
        [Authorize(Roles = "SysAdmin, Administrador, Gerente, DiretorArte")]
        public ActionResult CadastroPessoaFisica(int id)
        {
            var cli = new Pessoa_PF();
            if (id > 0)
            {
                cli = PessoaBll.GetPessoaFisicaCliente(db, id);
				cli.IdEstado = cli.Cidade.IdEstado;
                ViewBag.Estado = new SelectList(db.Estado.ToList(), "IdEstado", "NomeEstado", cli.IdEstado);
                ViewBag.Cidade = new SelectList(db.Cidade.Where(c => c.IdEstado == cli.Cidade.IdEstado), "IdCidade", "NomeCidade", cli.IdCidade);
            }
            else
            {
                cli.DataCadastro = DateTime.Today;
                cli.DataNascimento = new DateTime(1900, 01, 01);
                ViewBag.Estado = new SelectList(db.Estado.ToList(), "IdEstado", "NomeEstado");
                ViewBag.Cidade = new SelectList(db.Cidade.ToList().Take(0), "IdCidade", "NomeCidade");
                cli.UserName = "";
            }
            return View(cli);
        }

        [Authorize(Roles = "SysAdmin, Administrador, Gerente, DiretorArte")]
        public ActionResult CadastroPessoaJuridica(int id)
        {
            var cli = new Pessoa_PJ();
            if (id > 0)
            {
				cli = PessoaBll.GetPessoaJuridicaCliente(db, id);
                cli.DataCadastro = DateTime.Today;
				cli.IdEstado = cli.Cidade.IdEstado;
				ViewBag.Estado = new SelectList(db.Estado.ToList(), "IdEstado", "NomeEstado", cli.IdEstado);
				ViewBag.Cidade = new SelectList(db.Cidade.Where(c => c.IdEstado == cli.Cidade.IdEstado), "IdCidade", "NomeCidade", cli.IdCidade);
            }
            else
            {
                cli.DataCadastro = DateTime.Today;
                cli.DataAbertura = new DateTime(1900, 01, 01);
                ViewBag.Estado = new SelectList(db.Estado.ToList(), "IdEstado", "NomeEstado");
                ViewBag.Cidade = new SelectList(db.Cidade.ToList().Take(0), "IdCidade", "NomeCidade");
                cli.UserName = "";
            }
            return View(cli);
        }

        [Authorize(Roles = "SysAdmin, Administrador, Gerente, DiretorArte")]
        public ActionResult CadastroCliente(int id)
        {
            var cli = ClienteBll.GetCliente(db, id);
			cli.IdEstado = cli.Cidade.IdEstado;
			ViewBag.Estado = new SelectList(db.Estado.ToList(), "IdEstado", "NomeEstado", cli.IdEstado);
			ViewBag.Cidade = new SelectList(db.Cidade.Where(c => c.IdEstado == cli.Cidade.IdEstado), "IdCidade", "NomeCidade", cli.IdCidade);
            return View(cli);
        }
        #endregion

        #region Salvar
        [Authorize(Roles = "SysAdmin, Administrador, Gerente, DiretorArte")]
        public ActionResult SalvarClientePF(Pessoa_PF pessoa)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    var p = new Pessoa_PF();
                    if (pessoa.IdPessoa > 0)
                    {
                        p = PessoaBll.GetPessoaFisicaCliente(db, pessoa.IdPessoa);
                        TryUpdateModel(p);
                        db.Pessoa.ApplyCurrentValues(p);
                    }
                    else
                    {
                        TryUpdateModel(p);
                        p.TipoPessoa.Add(TipoPessoaBll.GetTipoPessoa(db, "Cliente"));
                        db.Pessoa.AddObject(p);
                    }
                    db.SaveChanges();
                    if (Request.IsAjaxRequest())
                    {
                        return Json(new { salvo = true, id = p.IdPessoa, username = p.UserName });
                    }
                    return RedirectToAction("Index");
                }
                catch (Exception ex)
                {
                    if (Request.IsAjaxRequest())
                    {
                        string msgEx;
                        if (ex.InnerException == null)
                        {
                            msgEx = ex.Message;
                        }
                        else
                        {
                            msgEx = ex.InnerException.Message;
                        }
                        return Json(new { salvo = false, error = msgEx });
                    }
                    ModelState.AddModelError(string.Empty, ex);
                    return View(pessoa);
                }
            }
            else
            {				
				if (Request.IsAjaxRequest())
				{
					var msgEx = "Houve um erro desconhecido e não foi possível executar a operação!<br /><br />Por favor, tente novamente mais tarde ou entre em contato com o Administrador do Sistema.";
					return Json(new { salvo = false, error = msgEx });
				}
                return View(pessoa);
            }
        }

        [Authorize(Roles = "SysAdmin, Administrador, Gerente, DiretorArte")]
        public ActionResult SalvarClientePJ(Pessoa_PJ pessoa)
        {
            if (ModelState.IsValid)
            {
                try
                {
					var p = new Pessoa_PJ();
                    if (pessoa.IdPessoa > 0)
                    {
						p = PessoaBll.GetPessoaJuridicaCliente(db, pessoa.IdPessoa); 
                        TryUpdateModel(p);
                        p.TipoPessoa.Add(TipoPessoaBll.GetTipoPessoa(db, "Cliente"));                        
                        db.Pessoa.ApplyCurrentValues(p);
                    }
                    else
                    {
                        TryUpdateModel(p);
                        p.TipoPessoa.Add(TipoPessoaBll.GetTipoPessoa(db, "Cliente"));
						if (pessoa.Fornecedor)
						{
							var pf = new Pessoa_PJ();
							TryUpdateModel(pf);
							pf.TipoPessoa.Add(TipoPessoaBll.GetTipoPessoa(db, "Fornecedor"));							
							db.Pessoa.AddObject(pf);
						}
                        db.Pessoa.AddObject(p);
                    }
                    db.SaveChanges();
                    if (Request.IsAjaxRequest())
                    {
                        return Json(new { salvo = true, id = p.IdPessoa });
                    }
                    return RedirectToAction("Index");
                }
                catch (Exception ex)
                {
                    if (Request.IsAjaxRequest())
                    {
                        string msgEx;
                        if (ex.InnerException == null)
                        {
                            msgEx = ex.Message;
                        }
                        else
                        {
                            msgEx = ex.InnerException.Message;
                        }
                        ViewBag.Erro = "Houve um erro na gravação dos dados!<br /><br />" + msgEx;
                    }
                    return View(pessoa);
                }
            }
            else
            {
				if (Request.IsAjaxRequest())
				{
					var msgEx = "Houve um erro desconhecido e não foi possível executar a operação!<br /><br />Por favor, tente novamente mais tarde ou entre em contato com o Administrador do Sistema.";
					return Json(new { salvo = false, error = msgEx });
				}
                return View(pessoa);
            }
        }
        #endregion

        #region Excluir
        [Authorize(Roles = "SysAdmin, Administrador, Gerente, DiretorArte, Funcionario")]
        public ActionResult Excluir(int id)
        {
            try
            {
                var cli = ClienteBll.GetCliente(db, id);
                var tp = TipoPessoaBll.GetTipoPessoa(db, 0, id);               
                cli.TipoPessoa.Remove(tp);
                db.Pessoa.DeleteObject(cli);
                db.SaveChanges();
                if (!string.IsNullOrWhiteSpace(cli.UserName))
                {
                    Roles.RemoveUserFromRole(cli.UserName, "Cliente");
                    Membership.DeleteUser(cli.UserName);
                }
                return Json(new { salvo = true });
            }
            catch (Exception ex)
            {
                string msgEx = "Houve um erro na gravação dos dados: <br /><br />";
                if (ex.InnerException == null)
                {
                    msgEx += ex.Message;
                }
                else
                {
                    msgEx += ex.InnerException.Message;
                }
                if (msgEx.Contains("REFERENCE constraint"))
                {
                    msgEx = "Este cliente não pode ser excluído pois ele está sendo usado em outros cadastros.";
                }
                return Json(new { salvo = false, error = msgEx });
            }
        }
        #endregion

        #region AutoComplete
        [Authorize(Roles = "SysAdmin, Administrador, Gerente, DiretorArte")]
        [HttpPost]
        public JsonResult AutoComplete(int filtro, string termoPesquisa)
        {
            var data = ClienteBll.AutoComplete(db, filtro, termoPesquisa, 10);
            return Json(data);
        }

        [Authorize(Roles = "SysAdmin, Administrador, Gerente, DiretorArte")]
        [HttpPost]
        public JsonResult AutoCompletePesquisaCliente(string termoPesquisa)
        {
            var data = ClienteBll.AutoComplete(db, termoPesquisa, 10);
            return Json(data);
        }

        [Authorize(Roles = "SysAdmin, Administrador, Gerente, DiretorArte")]
        [HttpPost]
        public JsonResult BuscaNomeCliente(int id)
        {
            var data = ClienteBll.BuscaNomeCliente(db, id);
            return Json(data);
        }
        #endregion

        #region Auxiliares
        [Authorize(Roles = "SysAdmin, Administrador, Gerente, DiretorArte")]
        [HttpPost]
        public JsonResult CarregarComboCidade(int idEstado)
        {
            var cidade = CidadeBll.GetCidadesPorEstado(db, idEstado);
            return new JsonResult { Data = new SelectList(cidade.ToList(), "IdCidade", "NomeCidade") };
        }

        [Authorize(Roles = "SysAdmin, Administrador, Gerente, DiretorArte")]
        [HttpGet]
        public JsonResult TipoCliente(int id)
        {
            var tipoCli = PessoaBll.GetPessoaTipoCliente(db, id);
            return Json(tipoCli, JsonRequestBehavior.AllowGet);
        }
        #endregion
    }
}
